﻿using BW.WMS.CodeEnum;
using BW.WMS.Model;
using BW.WMS.StockControl_GJH.Dto.Input;
using BW.WMS.StockControl_GJH.Dto.Output;
using BW.WMS.XKY;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Transactions;
using Volo.Abp.Application.Services;
using Volo.Abp.Domain.Repositories;

namespace BW.WMS.StockControl_GJH
{
    public class StandingAppService : ApplicationService, IStandingAppService
    {

        private readonly IRepository<StandingBookModel, Guid> _standingBookRepository;
        private  readonly IRepository<StandingBookSubModel, Guid> _standingBooksubRepository;
        private readonly IRepository<Dm_Warehouser, Guid> _warehouserRepository;
        private readonly IRepository<Dm_Item, Guid> _itemRepository;
        private readonly IRepository<Dm_Librarylocation, Guid> _librarylicationRepository;
        private readonly IRepository<UserModel, Guid> _userRepository;


        public StandingAppService(IRepository<StandingBookModel, Guid> standingBookRepository, IRepository<StandingBookSubModel, Guid> standingBooksubRepository, IRepository<Dm_Warehouser, Guid> warehouserRepository, IRepository<Dm_Item, Guid> itemRepository, IRepository<Dm_Librarylocation, Guid> librarylicationRepository, IRepository<UserModel, Guid> userRepository)
        {
            _standingBookRepository = standingBookRepository;
            _standingBooksubRepository = standingBooksubRepository;
            _warehouserRepository = warehouserRepository;
            _itemRepository = itemRepository;
            _librarylicationRepository = librarylicationRepository;
            _userRepository = userRepository;
        }

        /// <summary>
        /// 添加库存盘点
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<ApiResult<int>> LatestStandingBook(LatestStandingBookInput input)
        {
            if (input.WarehouseId == "")
            {
                return new ApiResult<int>()
                {
                    Code = ApiEnum.Error,
                    Message = "请选择仓库",
                    Data = 0
                };
            }
            var warehouse = await _warehouserRepository.GetQueryableAsync();
            var a = warehouse.Where(x => x.Status == 2 && x.Warehouseid == input.WarehouseId).FirstOrDefault();

            if (a == null)
            {
                return new ApiResult<int>()
                {
                    Code = ApiEnum.Error,
                    Message = "该仓库暂未锁定，请锁定后再进行盘点",
                    Data = 0
                };
            }
            var standingBook = ObjectMapper.Map<LatestStandingBookInput, StandingBookModel>(input);
            input.CreationTime = DateTime.Now;

            using (var tran = new TransactionScope())
            {
                try
                {
                    _standingBookRepository.InsertAsync(standingBook);
                    foreach (var item in input.StandingBookSub)
                    {

                        var sub = ObjectMapper.Map<Dto.Input.StandingBookSubInput, StandingBookSubModel>(item);
                        sub.StandingBookOod = standingBook.StandingBookOod;
                        _standingBooksubRepository.InsertAsync(sub);
                    }
                    tran.Complete();
                }
                catch (Exception ex)
                {
                    Console.WriteLine("事务失败: " + ex.Message);
                    return new ApiResult<int>()
                    {
                        Code = ApiEnum.Error,
                        Message = "失败"
                    };
                }
            }


            return new ApiResult<int>()
            {
                Code = ApiEnum.Success,
                Message = "盘点添加成功",
                Data = 1
            };


        }

        /// <summary>
        /// 获取盘点信息
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<ApiPaging<GetStandingbookOutput>> GetStanding(GetStandinginput input)
        {
            var standingbook =await _standingBookRepository.GetQueryableAsync();
            var standingbooksub =await _standingBooksubRepository.GetQueryableAsync();
            var warehouse =await _warehouserRepository.GetQueryableAsync();
            var item =await _itemRepository.GetQueryableAsync();
            var librarylocation =await _librarylicationRepository.GetQueryableAsync();
            var user =await _userRepository.GetQueryableAsync();
            if (!string.IsNullOrEmpty(input.WarehouseId))
            {
                standingbook = standingbook.Where(a => a.WarehouseId == input.WarehouseId);
            }
            if (!string.IsNullOrEmpty(input.StandingBookType))
            {
                standingbook = standingbook.Where(a => a.StandingBookType == input.StandingBookType);
            }
            if (!string.IsNullOrEmpty(input.StandingBookOod))
            {
                standingbook = standingbook.Where(a => a.StandingBookOod == input.StandingBookOod);
            }

           
            var linq = from a in standingbook
                       join b in standingbooksub on a.StandingBookOod equals b.StandingBookOod
                       join c in warehouse on a.WarehouseId equals c.Warehouseid
                       join d in item on b.ItemId equals d.Itemid
                       join e in librarylocation on b.StorageLocationID equals e.Librarylocationid
                       join f in user on a.Empid equals f.Id.ToString()
                       select new GetStandingbookOutput
                       {
                           Id=a.Id.ToString(),
                           StandingBookOod = a.StandingBookOod,
                           StandingBookType = a.StandingBookType,
                           StandingBookOpenDate = a.StandingBookOpenDate,
                           StandingBookCloseDate = a.StandingBookCloseDate,
                           WarehouseId = c.Warehousename,
                           Empid = f.TrueName,
                           StandingBookRemark = a.StandingBookRemark,
                           ItemId = d.Itemname,
                           StorageLocationID = e.Librarylocationname,
                           StandingBookNumber = b.StandingBookNumber,
                           CreationTime = a.CreationTime,
                           Price=b.Price,
                           ProfitMoney=b.ProfitMoney,
                           ProfitNumber=b.ProfitNumber
                       };

            // 新增：分组合并
            var grouped = linq
                .GroupBy(x => x.Id)
                .Select(g => new GetStandingbookOutput
                {
                    Id = g.Key,
                    StandingBookOod = g.First().StandingBookOod,
                    StandingBookType = g.First().StandingBookType,
                    StandingBookOpenDate = g.First().StandingBookOpenDate,
                    StandingBookCloseDate = g.First().StandingBookCloseDate,
                    WarehouseId = g.First().WarehouseId,
                    Empid = g.First().Empid,
                    StandingBookRemark = g.First().StandingBookRemark,
                    ItemId = string.Join(",", g.Select(x => x.ItemId)), // 拼接Itemname
                    StorageLocationID = g.First().StorageLocationID,
                    StandingBookNumber = g.Sum(x => x.StandingBookNumber), // 累加
                    CreationTime = g.First().CreationTime,
                    Price = g.Sum(x => x.Price), // 累加
                    ProfitMoney = g.Sum(x => x.ProfitMoney), // 累加
                    ProfitNumber = g.Sum(x => x.ProfitNumber), // 累加
                    Standingresult = g.Sum(x => x.ProfitMoney) > 0 ? "盘盈" : 
                                    g.Sum(x => x.ProfitMoney) < 0 ? "盘亏" : "已完成" // 新增字段计算
                });

            var model = grouped.OrderBy(a => a.StandingBookOod)
                .Skip((input.PageIndex - 1) * input.PageSize)
                .Take(input.PageSize)
                .ToList();

            return new ApiPaging<GetStandingbookOutput>
            {
                Code = ApiEnum.Success,
                Message = "查询成功",
                TotalCount = grouped.Count(),
                PageData = model,
                TotalPages = (int)Math.Ceiling(grouped.Count() / (double)input.PageSize)
            };

        }




        /// <summary>
        /// 获取盘点的一条信息用于反显
        /// </summary>
        /// <param name="StandingBookOod"></param>
        /// <returns></returns>
        public async Task<ApiResult<ShowStadingOutput>> ShowStading(string StandingBookOod)
        {
            // 查询主表
            var standingBook = await _standingBookRepository.FirstOrDefaultAsync(x => x.StandingBookOod == StandingBookOod);
            if (standingBook == null)
            {
                return new ApiResult<ShowStadingOutput>
                {
                    Code = ApiEnum.Error,
                    Message = "未找到对应的盘点主表数据",
                    Data = null
                };
            }

            // 查询子表
            var standingBookSubs = await _standingBooksubRepository.GetListAsync(x => x.StandingBookOod == StandingBookOod);

            // 实体转DTO（可用ObjectMapper，也可手动）
            var subInputs = standingBookSubs.Select(sub => new Dto.Output.StandingBookSubInput
            {
                StandingBookOod = sub.StandingBookOod,
                ItemId = sub.ItemId,
                StorageLocationID = sub.StorageLocationID,
                StandingBookNumber = sub.StandingBookNumber,
                ProfitNumber = sub.ProfitNumber,
                StandingBookType = sub.StandingBookType,
                Price = sub.Price,
                ProfitMoney = sub.ProfitMoney,
                StandingBookRemark = sub.StandingBookRemark
            }).ToList();

            // 组装输出
            var output = new ShowStadingOutput
            {
                StandingBookOod = standingBook.StandingBookOod,
                StandingBookType = standingBook.StandingBookType,
                StandingBookOpenDate = standingBook.StandingBookOpenDate,
                StandingBookCloseDate = standingBook.StandingBookCloseDate,
                WarehouseId = standingBook.WarehouseId,
                Empid = standingBook.Empid,
                StandingBookRemark = standingBook.StandingBookRemark,
                StandingBookSub = subInputs
            };

            return new ApiResult<ShowStadingOutput>
            {
                Code = ApiEnum.Success,
                Message = "查询成功",
                Data = output
            };
        }



        /// <summary>
        /// 修改盘点
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<ApiResult<int>> UpdateStading(UpdateStadingInput input)
        {
            // 查询主表
            var standingBook = await _standingBookRepository.FirstOrDefaultAsync(x => x.StandingBookOod == input.StandingBookOod);
            if (standingBook == null)
            {
                return new ApiResult<int>
                {
                    Code = ApiEnum.Error,
                    Message = "未找到对应的盘点主表数据",
                    Data = 0
                };
            }

            // 更新主表字段
            standingBook.StandingBookType = input.StandingBookType;
            standingBook.StandingBookOpenDate = input.StandingBookOpenDate;
            standingBook.StandingBookCloseDate = input.StandingBookCloseDate;
            standingBook.WarehouseId = input.WarehouseId;
            standingBook.Empid = input.Empid;
            standingBook.StandingBookRemark = input.StandingBookRemark;

            // 查询并删除原有子表
            var oldSubs = await _standingBooksubRepository.GetListAsync(x => x.StandingBookOod == input.StandingBookOod);
            foreach (var sub in oldSubs)
            {
                await _standingBooksubRepository.DeleteAsync(sub);
            }

            // 插入新的子表
            foreach (var subInput in input.StandingBookSub)
            {
                var newSub = new StandingBookSubModel
                {
                    StandingBookOod = subInput.StandingBookOod,
                    ItemId = subInput.ItemId,
                    StorageLocationID = subInput.StorageLocationID,
                    StandingBookNumber = subInput.StandingBookNumber,
                    ProfitNumber = subInput.ProfitNumber,
                    StandingBookType = subInput.StandingBookType,
                    Price = subInput.Price,
                    ProfitMoney = subInput.ProfitMoney,
                    StandingBookRemark = subInput.StandingBookRemark
                };
                await _standingBooksubRepository.InsertAsync(newSub);
            }

            // 更新主表
            await _standingBookRepository.UpdateAsync(standingBook);

            return new ApiResult<int>
            {
                Code = ApiEnum.Success,
                Message = "修改成功",
                Data = 1
            };
        }


        /// <summary>
        /// 删除盘点
        /// </summary>
        /// <param name="StandingBookOod"></param>
        /// <returns></returns>
        public async Task<ApiResult<int>> DeleteStading(string StandingBookOod)
        {
            // 查询主表数据
            var standingBook = await _standingBookRepository.FirstOrDefaultAsync(x => x.StandingBookOod == StandingBookOod);
            if (standingBook == null)
            {
                return new ApiResult<int>
                {
                    Code = ApiEnum.Error,
                    Message = "未找到对应的盘点主表数据",
                    Data = 0
                };
            }

            // 查询子表数据
            var standingBookSubs = await _standingBooksubRepository.GetListAsync(x => x.StandingBookOod == StandingBookOod);

            using (var tran = new TransactionScope())
            {
                try
                {
                    // 删除子表数据
                    foreach (var sub in standingBookSubs)
                    {
                        await _standingBooksubRepository.DeleteAsync(sub);
                    }

                    // 删除主表数据
                    await _standingBookRepository.DeleteAsync(standingBook);

                    tran.Complete();
                }
                catch (Exception ex)
                {
                    Console.WriteLine("删除事务失败: " + ex.Message);
                    return new ApiResult<int>
                    {
                        Code = ApiEnum.Error,
                        Message = "删除失败",
                        Data = 0
                    };
                }
            }

            return new ApiResult<int>
            {
                Code = ApiEnum.Success,
                Message = "删除成功",
                Data = 1
            };
        }


        /// <summary>
        /// 获取用户
        /// </summary>
        /// <returns></returns>
        public async Task<ApiPaging<UserModel>> GetUser()
        {
            var user = await _userRepository.GetListAsync();

            return new ApiPaging<UserModel>()
            {
                Code = ApiEnum.Success,
                Message = "获取成功",
                PageData = user
            };
        }

    }
}
